package com.zrsx.managemodel.service.serviceImpl;

import com.mysql.cj.log.Log;
import com.zrsx.managemodel.common.constants.ServiceType;
import com.zrsx.managemodel.common.constants.Type;
import com.zrsx.managemodel.common.dto.CreditDTO;
import com.zrsx.managemodel.common.dto.CreditDimensionDTO;
import com.zrsx.managemodel.common.entity.CreditInterpretation;
import com.zrsx.managemodel.common.result.Result;
import com.zrsx.managemodel.mapper.CreditDimensionMapper;
import com.zrsx.managemodel.mapper.CreditMapper;
import com.zrsx.managemodel.service.CreditManageService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zachary.commonmodule.entity.entity.CreditDimension;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class CreditManageServiceImpl implements CreditManageService {
    @Autowired
    private CreditDimensionMapper creditDimensionMapper;
    @Autowired
    private CreditMapper creditMapper;
    @Autowired
    private OpenFeignService openFeignService;
    @Autowired
    private StringRedisTemplate redisTemplate;


    private static final String CREDIT_RANK_KEY = "credit:rank";

    /**
     * 更新信用分详情
     * @param creditDimensionDTO
     * @param creditInterpretation
     */
    @Override
    public void updateCredit(CreditDimensionDTO creditDimensionDTO, CreditInterpretation creditInterpretation) {
        System.out.println("--------ServiceImpl:"+creditDimensionDTO);
        CreditDimension creditDimension = new CreditDimension();
        BeanUtils.copyProperties(creditDimensionDTO, creditDimension);
        creditDimension.setUpdateTime(LocalDateTime.now());
        //如果更新基础信息，则非加减，而是直接更新
        if(creditDimensionDTO.getDimensionType().equals("基本信息")){
            creditDimensionDTO.setChangeCredit(creditDimensionDTO.getChangeCredit()
                     - openFeignService.getCreditDimension(creditDimensionDTO.getUserId(),creditDimensionDTO.getDimensionType()).getData());
        }
        //得到完整的解读描述字符串
        String fullDesc = getDesc(creditInterpretation);
        creditDimension.setDimensionDesc(fullDesc);
        System.out.println(creditDimension);
        //计算更新后的分数
        int newScore = openFeignService.getCreditDimension(creditDimensionDTO.getUserId(),creditDimensionDTO.getDimensionType()).getData()
                + creditDimensionDTO.getChangeCredit();
        creditDimension.setDimensionScore(newScore);
        creditDimension.setUpdateTime(LocalDateTime.now());
        System.out.println("--------ServiceImpl:"+newScore);
        int newTotalScore = 0;
        //如果更新的不是总分，还要把总分一起更新了
        if(!creditDimensionDTO.getDimensionType().equals("总信用分")){
            CreditDimension total = new CreditDimension();
            BeanUtils.copyProperties(creditDimension, total);
            newTotalScore = openFeignService.getCreditDimension(creditDimensionDTO.getUserId(),"总信用分").getData()
                    + creditDimensionDTO.getChangeCredit();
            total.setDimensionType("总信用分");
            total.setDimensionScore(newTotalScore);
            System.out.println("更新总信用分");
            creditDimensionMapper.updateCredit(total);
        }
        //更新credit_score数据
        creditMapper.updateCredit(creditDimensionDTO.getUserId(), newTotalScore);
        int newLevel = updateLevel(newTotalScore);
        creditMapper.updateCreditLevel(creditDimensionDTO.getUserId(), newLevel);
        //更新Redis
        redisTemplate.opsForZSet().add(CREDIT_RANK_KEY, String.valueOf(creditDimensionDTO.getUserId()), newTotalScore);
        creditDimensionMapper.updateCredit(creditDimension);
    }


    /**
     * 更新信用等级逻辑
     * @param newTotalScore
     * @return
     */
    public Integer updateLevel(Integer newTotalScore){
        // 850+为信用极好 850-750为信用较好 750-600信用一般 600-450信用较差 450-信用极差 -1是未评级
        if(newTotalScore >= 850){
            return 1;
        }else if(newTotalScore >= 750){
            return 2;
        }else if(newTotalScore >= 600){
            return 3;
        }else if(newTotalScore >= 450){
            return 4;
        }else if(newTotalScore == 0) {
            return -1;
        } else{
            return 5;
        }
    }

    /**
     * 新增用户信用分
     */
    @Transactional
    @Override
    public void addCredit(CreditDTO creditDTO) {
        //1.插入用户信用分及排名表
        creditMapper.addCredit(creditDTO);
        creditMapper.updateCreditLevel(creditDTO.getUserId(), updateLevel(creditDTO.getScore()));
        log.info("新增用户信用分数据: {}", creditDTO);
        //2.插入用户信用分维度数据 --
        //一共插入五条，在Mapper层实现
        List<CreditDimension> creditDimensions = new ArrayList<>();
        Field[] fields = Type.class.getDeclaredFields();
        for (Field field : fields) {
            if (Modifier.isStatic(field.getModifiers()) && field.getType() == String.class) {
                try {
                    String dimensionType = (String) field.get(null); // 获取静态字段值
                    CreditDimension dimension = new CreditDimension();
                    dimension.setUserId(creditDTO.getUserId());
                    dimension.setDimensionType(dimensionType);
                    dimension.setDimensionDesc("初始插入");
                    dimension.setUpdateTime(LocalDateTime.now());

                    if(creditDTO.getScore()!=0 &&
                            (dimensionType == "总信用分" || dimensionType == "基本信息")){
                        dimension.setDimensionScore(creditDTO.getScore());
                    }else {
                        dimension.setDimensionScore(0);
                    }
                    log.info("新增信用分维度数据: {}", dimension);
                    creditDimensions.add(dimension);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        creditDimensionMapper.batchInsertCredit(creditDimensions);
    }

    /**
     * 删除信用分数据
     * @param userId
     */
    @Override
    public void deleteCredit(Integer userId) {
        //1.删除信用分排名表数据
        creditMapper.deleteCredit(userId);
        //2.删除信用分维度表数据
        creditDimensionMapper.deleteCredit(userId);
    }


    /**
     * 更新dimension_type='总信用分' 且 last_update_time在指定时间范围的记录的 dimension_desc 字段
     */
    @Override
    public int updateTotalCreditDescBetween(LocalDateTime start, LocalDateTime end) {
        // 1. 查询昨天被更新过的“总信用分”维度记录
        List<CreditDimension> list = creditDimensionMapper.selectByDimensionTypeAndUpdateTime("总信用分", start, end);

        int updateCount = 0;

        for (CreditDimension record : list) {
            Integer userId = record.getUserId();
            Integer originalScore = record.getDimensionScore();

            // 2. 调用 Feign 获取对应分数的信用解读
            Result<CreditInterpretation> interpretationResult = openFeignService.getCreditInterpretation(userId);
            System.out.println("用户：" + userId + "，分数：" + originalScore + "，解读：" + interpretationResult.getData());

            if (interpretationResult.getData() == null) {
                continue;
            }

            // 3. 生成完整维度解读字符串
            String newDesc = getDesc(interpretationResult.getData());

            // 4. 只更新 dimension_desc，不更新 last_update_time
            int rows = creditDimensionMapper.updateDimensionDesc(userId, "总信用分", originalScore, newDesc);
            if (rows > 0) {
                updateCount += rows;
            }
        }

        return updateCount;
    }

    public String getDesc(CreditInterpretation interpretation){
        StringBuilder sb = new StringBuilder();
        sb.append("信用报告解读\n");
        sb.append("================================\n");
        sb.append(String.format("信用分数：%d分\n", interpretation.getCreditScore()));
        sb.append(String.format("信用等级：%s\n", interpretation.getCreditLevel()));

        // 特殊处理未评级情况，直接返回
        if (interpretation.getCreditScore() == 0 && "未评级".equals(interpretation.getCreditLevel())) {
            return sb.toString();
        }

        // 正常情况输出完整解读
        sb.append(String.format("综合解读：%s\n", interpretation.getInterpretation()));
        sb.append("\n行为建议：\n");
        List<String> tips = interpretation.getBehaviorTips();
        for (int i = 0; i < tips.size(); i++) {
            sb.append(String.format("%d. %s\n", i + 1, tips.get(i)));
        }
        sb.append("\n================================\n");
        sb.append("温馨提示：\n");
        sb.append("- 信用分每月更新，请持续关注您的信用状况\n");
        sb.append("- 良好的信用记录可为您带来更多金融服务便利\n");

        return sb.toString();
    }

}




